#include <iostream>
#include <cstring>
#include <unistd.h>

using namespace std;

class Human {
private:
    int a;
public:
    virtual ~Human(){cout << "~Human()" << endl;}
    virtual void eating(void) {cout << "using hand to eat" << endl;}
    virtual Human* test(void) {cout << "Human test" << endl; return this;}
};

class Englishman : public Human {
public:
    virtual ~Englishman(){cout << "~Englishman()" << endl;}
    void eating(void) {cout << "using knife to eat" << endl;}
    virtual Englishman* test(void) {cout << "Englishman test" << endl; return this;}
};

class Chinese : public Human {
public:
    virtual ~Chinese(){cout << "~Chinese()" << endl;}
    void eating(void) {cout << "using chopsticks to eat" << endl;}
    virtual Chinese* test(void) {cout << "Chinese test" << endl; return this;}
};

class Guangximan : public Chinese {
public:
    virtual ~Guangximan(){cout << "~Guangximan()" << endl;}
};


void test_eating(Human& h) {
    h.eating();
}

void test_return(Human& h) {
    h.test();

    Englishman *pe;
    Chinese *pc;
    Guangximan *gc;

    if (pe = dynamic_cast<Englishman *>(&h)) {
        cout << "This Human is Englishman" << endl;
    }
    if (pc = dynamic_cast<Chinese *>(&h)) {
        cout << "This Human is Chinese" << endl;
    }
    if (gc = dynamic_cast<Guangximan *>(&h)) {
        cout << "This Human is Guangximan" << endl;
    }
}

int main() {
//    Human* h = new Human;
//    Englishman* e = new Englishman;
//    Chinese* c = new Chinese;
//    cout << "sizeof(e): " << sizeof(e) << endl;
//
//    test_eating(h);
//    test_eating(e);
//    test_eating(c);

//    Human *p[3] = {h, e, c};
//    for (int i = 0; i < 3; ++i) {
//        p[i]->eating();
//        delete p[i];
//    }

    Human h;
    Englishman e;
    Chinese c;
    Guangximan gx;

    test_return(h);
    test_return(e);
    test_return(c);
    test_return(gx);

    Englishman *pe;
    pe = static_cast<Englishman *>(&h);

//    Englishman *pe2;
//    pe2 = static_cast<Englishman *>(&gx);

    Chinese *pe2;
    pe2 = static_cast<Chinese *>(&gx);

    return 0;
}
